home *** CD-ROM | disk | FTP | other *** search
- TITLE GLOVEDEL - Powerglove timing and i/o support
- NAME GLOVEDEL
-
- ; SPECIAL VERSION FOR COMBO GLOVE/SEGA DRIVER PORTS
- ; rewritten 20/12/93
-
- COMMENT $
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
-
- Algorithms, assembler by Dave Stampe, 22/12/93
-
- $
-
- .MODEL large
- .386
-
- .DATA
-
- extrn _counts_per_tick ; MUST contain value programmed into timer
-
- EXTRN _glove_in_port ; GLOVE INTERFACE SPECS
- EXTRN _glove_out_port ; SET UP IN C CODE
-
- EXTRN _glove_none_mask
- EXTRN _glove_data_mask
- EXTRN _glove_latch_mask
- EXTRN _glove_clock_mask
- EXTRN _glove_clock_latch
-
- EXTRN _glove_bit_delay
-
- EXTRN _port_image
- EXTRN _glove_write_mask
-
-
- .CODE devices
-
-
- READ_TIMER MACRO ; result will be in ax
- pushf
- cli
- mov al,00h ;/* read PC timer */
- out 043h,al
- nop
- nop
- in al,040h
- mov ah,al
- nop
- nop
- in al,040h
- xchg al,ah
- popf
- ENDM
-
- WRITE_TIMER MACRO ; write from BX
- pushf
- cli
- mov al,34h
- out 43h,al ; prepare for write
- xor al,al
- nop
- mov al,bl
- out 40h,al
- nop
- mov al,bh
- out 40h,al
- popf
- ENDM
-
-
-
- ; bit delay macro for byte read, line toggle
-
- bitdelay macro
- local _localloop
- mov cx,_glove_bit_delay
- _localloop:
- in al,41h
- loop _localloop
- endm
-
-
-
- ;
- ; int timed_glove_delay(int count); /* returns time in 1.1925 MHZ ticks */
- ; /* to perform <count> delay steps */
-
- PUBLIC _timed_glove_delay
-
- count equ [bp+6]
-
- _timed_glove_delay proc far
-
- push bp
- mov bp,sp
- push cx
- push dx
- pushf
-
- mov bx,0 ; reset timer for no ovf
- WRITE_TIMER ; this changes timing by factor of 2?
-
- cli
- READ_TIMER
- mov bx,ax
-
- mov cx,count
- caloop: in al,40h ; do delay
- loop caloop
-
- READ_TIMER
- sub ax,bx ; assumes default, count rollover at 65536
- neg ax
-
- push ax
- mov bx,_counts_per_tick ; restore timer
- WRITE_TIMER
- pop ax
-
- popf
- pop dx
- pop cx
- mov sp,bp
- pop bp
- ret
-
- _timed_glove_delay endp
-
-
- ;
- ; int glove_delay(int count); /* performs <count> delay steps */
- ;
-
- PUBLIC _glove_delay
-
- count equ [bp+6]
-
- _glove_delay proc far
-
- push bp
- mov bp,sp
- push cx
- push dx
- mov cx,count
-
- gdel: in al,41h
- loop gdel
-
- pop dx
- pop cx
- mov sp,bp
- pop bp
- ret
-
- _glove_delay endp
-
-
-
- ;
- ; int get_glove_byte(); /* reads a byte from glove */
- ;
-
- PUBLIC _get_glove_byte
-
- _get_glove_byte proc far
-
- push bp
- mov bp,sp
- push si
- push cx
- push dx
-
- mov dx,_glove_out_port
- mov si,_glove_in_port
-
- mov ax,_glove_clock_mask ; preset lines
- pushf
- cli
- mov ah,BYTE PTR _glove_write_mask
- not ah
- and ah,BYTE PTR _port_image
- or al,ah
- mov BYTE PTR _port_image,al
- out dx,al ; output data
- popf
- bitdelay
-
- mov ax,_glove_clock_latch
- pushf
- cli
- mov ah,BYTE PTR _glove_write_mask
- not ah
- and ah,BYTE PTR _port_image
- or al,ah
- mov BYTE PTR _port_image,al
- out dx,al ; output data
- popf
- bitdelay
-
- mov ax,_glove_clock_mask
- pushf
- cli
- mov ah,BYTE PTR _glove_write_mask
- not ah
- and ah,BYTE PTR _port_image
- or al,ah
- mov BYTE PTR _port_image,al
- out dx,al ; output data
- popf
- bitdelay
-
- mov bx,8000h ; clear accumulator
-
- bitloop:
- xchg si,dx ; add bit to accumulator
- in al,dx
- xchg si,dx
- test al,BYTE PTR _glove_data_mask
- jz z0
- or bl,bh
- z0: ; next bit
- shr bh,1
- jz endbyte
-
- mov ax,_glove_none_mask ; pulse clock line
- pushf
- cli
- mov ah,BYTE PTR _glove_write_mask
- not ah
- and ah,BYTE PTR _port_image
- or al,ah
- mov BYTE PTR _port_image,al
- out dx,al ; output data
- popf
- bitdelay
-
- mov ax,_glove_clock_mask
- pushf
- cli
- mov ah,BYTE PTR _glove_write_mask
- not ah
- and ah,BYTE PTR _port_image
- or al,ah
- mov BYTE PTR _port_image,al
- out dx,al ; output data
- popf
- bitdelay
- jmp bitloop
-
- endbyte:
- mov ax,bx
- xor ah,ah
- pop dx
- pop cx
- pop si
- mov sp,bp
- pop bp
- ret
-
- _get_glove_byte endp
-
-
- ;
- ; void set_glove_bits(int data); /* sets glove clock, data lines */
- ; /* and does a bit delay */
-
- PUBLIC _set_glove_bits
-
- bits equ [bp+6]
-
- _set_glove_bits proc far
-
- push bp
- mov bp,sp
- push dx
- mov dx,_glove_out_port
- mov ax,bits
-
- pushf
- cli
- and al,BYTE PTR _glove_write_mask
- mov ah,BYTE PTR _glove_write_mask
- not ah
- and ah,BYTE PTR _port_image
- or al,ah
- mov BYTE PTR _port_image,al
- out dx,al ; output data
- popf
-
- push cx
- bitdelay
- pop cx
-
- pop dx
- mov sp,bp
- pop bp
- ret
-
- _set_glove_bits endp
-
- end
-
-